'''
Back end for Panera workflow (Winter Intensives Lab 6)

This file is where you "wire" together the steps in the process.
'''

# these next few lines import some of the WMP functions we will
# use in this file.
from backend.backend import Backend
from workflow.task import Task
from workflow.result import Result 
from workflow.flowData import Status

class PaneraBackend(Backend):
    '''
    The PaneraBackend "class" is a collection of the "methods" (functions) that do the actual
    wiring together of the steps in the food ordering/delivery process.
    
    A back end will always include the methods __init__ and wire and will also include a method
    to handle each event that occurs in the process.  
    '''
   
    def __init__(self): 
        # Specify the workflow name:       
        Backend.__init__(self, "Panera")  # !!! be sure you update the workflow name

    def wire(self):
        '''
        The wire method is where we tell MWP which tasks to keep track of.
        To register a task, you will need to add a line of code that looks
        like this:
        self.register_result_listener("RoleName", "TaskName", self.method_name)
        Where: RoleName is the person who did the task
               TaskName is the name of the task they did
               self.method_name refers to a method in this class which should respond to
                                the task being completed.
        '''
        
        # !!! add a line of code here to register the step where a food order is taken.
        self.register_result_listener("Customer", "EnterOrder", self.food_order_entered)
        # !!! add a line of code here to register the step where food is prepared.
        self.register_result_listener("Chef", "PrepareFood", self.food_prepared)
        # !!! add a line of code here to register the step where quality is checked.
        self.register_result_listener("Chef", "CheckQuality", self.quality_checked)
        # !!! add a line of code here to register the step where food is picked up.
        self.register_result_listener("Driver", "PickUpFood", self.food_pickedup)
        # !!! add a line of code here to register the step where food is delivered.
        self.register_result_listener("Driver", "DeliverFood", self.food_delivered)
        
        self.register_result_listener("Customer", "GetFeedback", self.get_feedback)

    def food_order_entered(self, results):
        '''
        This method (i.e. function) gets called to update data and schedule any tasks
        necessary after a food order is entered.  Specifically, this function
        will set the status to "complete" on the "take food order" task
        and assigns the preparation of this food item to the Restaurant/Chef.
        '''
        for result in results:  # repeat the following actions for each result
            task = Task.construct_from_result(result, "Chef", "PrepareFood")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)

    def food_prepared(self, results):
        '''
        This method (i.e. function) gets called to update data and schedule any tasks
        necessary after a food order is prepared.  Specifically, this function
        will set the status to "complete" on the "prepare food" task
        and assigns the delivery of this food item to the driver.
        '''
        for result in results:  # repeat the following actions for each result
            task = Task.construct_from_result(result, "Chef", "CheckQuality")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
            
    def quality_checked(self, results):
        for result in results:
            if result.data['qualitycontrol'] == "Pass Quality":
                task = Task.construct_from_result(result, "Driver", "PickUpFood")
                self.workflow.add(task) # add the new task to the workflow
                self.workflow.update_status(result, Status.COMPLETE)
            else: 
                task = Task.construct_from_result(result, "Chef", "PrepareFood")
                self.workflow.add(task) # add the new task to the workflow
                self.workflow.update_status(result, Status.COMPLETE)

    def food_pickedup(self, results):
        for result in results:  # repeat the following actions for each result
            task = Task.construct_from_result(result, "Driver", "DeliverFood")
            self.workflow.add(task) # add the new task to the workflow
            self.workflow.update_status(result, Status.COMPLETE)
            
    def food_delivered(self, results):
        for result in results:  # repeat the following actions for each result
            task = Task.construct_from_result(result, "Customer", "GetFeedback")
            self.workflow.add(task) # add the new task to the workflow            
            self.workflow.update_status(result, Status.COMPLETE)
            
    def get_feedback(self, results):
        for result in results:  # repeat the following actions for each result
            self.workflow.update_status(result, Status.COMPLETE)     

'''
Finally, this last bit of code is fine as it is and you do not need to change it.
It initialize the backend by running the __init__ method
of the PaneraBackend class (above), among other things.
'''
if __name__ == '__main__':
    backend = PaneraBackend()